<template>
  <div class="flap-card-wrapper" v-show="flapCardVisible">
    <div class="flap-card-bg" :class="{'animation': runFlapCardAnimation}" v-show="runFlapCardAnimation">
<!--      遍历出四个圆形，分为左部和右部-->
      <div class="flap-card" v-for="(item, index) of flapCardList" :key="index" :style="{zIndex: item.zIndex}">
        <div class="flap-card-circle">
          <div class="flap-card-semi-circle flap-card-semi-circle-left"
               :style="semiCircleStyle(item, 'left')" ref="left"></div>
          <div class="flap-card-semi-circle flap-card-semi-circle-right"
               :style="semiCircleStyle(item, 'right')" ref="right"></div>
        </div>
      </div>
<!--      遍历出dom来生成小球-->
      <div class="point-wrapper">
        <div class="point" :class="{'animation': runPointAnimation}" v-for="item of pointList" :key="item"></div>
      </div>
    </div>
    <div class="book-card" :class="{'animation': runBookCardAnimation}" v-show="runBookCardAnimation">
      <div class="book-card-wrapper">
        <div class="img-wrapper">
          <img class="img" :src="data ? data.cover : ''">
        </div>
        <div class="content-wrapper">
          <div class="content-title">{{data ? data.title : ''}}</div>
          <div class="content-author sub-title-medium">{{data ? data.author : ''}}</div>
          <div class="content-category">{{categoryText()}}</div>
        </div>
        <div class="read-btn" @click.stop="showBookDetail(data)">{{$t('home.readNow')}}</div>
      </div>
    </div>
    <div class="close-btn-wrapper" @click="close">
      <span class="iconfont icon">&#xe725;</span>
    </div>
  </div>
</template>

<script>
import { storeHomeMixin } from '../../utils/mixin'
import { flapCardList, categoryText } from '../../utils/store'

export default {
  name: 'FlapCard',
  mixins: [storeHomeMixin],
  props: {
    // data的数据是网络请求，所以需要时间
    data: Object
  },
  data () {
    return {
      // 引入store中的flapCardList数据
      flapCardList,
      front: 0,
      back: 1,
      intervalTime: 25,
      runFlapCardAnimation: false,
      pointList: null,
      runPointAnimation: false,
      runBookCardAnimation: false
    }
  },
  watch: {
    flapCardVisible (v) {
      // 监听卡片的变量，当值为true是启动动画
      if (v) {
        this.runAnimation()
      }
    }
  },
  methods: {
    // 使用预设好的样式风格
    semiCircleStyle (item, dir) {
      return {
        // 背景颜色
        backgroundColor: `rgb(${item.r}, ${item.g}, ${item.b})`,
        backgroundSize: item.backgroundSize,
        backgroundImage: dir === 'left' ? item.imgLeft : item.imgRight
      }
    },
    // ****************** //
    // 关闭动画和卡片 //
    close () {
      this.stopAnimation()
      this.setFlapCardVisible(false)
    },
    stopAnimation () {
      if (this.task) {
        clearInterval(this.task)
      }
      if (this.timeout) {
        clearInterval(this.timeout)
      }
      if (this.timeout2) {
        clearInterval(this.timeout2)
      }
      this.reset()
    },
    // ****************** //
    // 动画启动
    runAnimation () {
      // 1.先进行一个弹出的动画，时长为.3秒，所以后续动画延迟播放
      this.runFlapCardAnimation = true
      this.timeout = setTimeout(() => {
        this.startFlapCardAnimation()
        this.startPointAnimation()
      }, 300)
      // 2.在2500秒后关闭动画显示卡片
      this.timeout2 = setTimeout(() => {
        this.stopAnimation()
        this.runBookCardAnimation = true
      }, 2500)
    },
    // 1.1开始翻转
    startFlapCardAnimation () {
      this.prepare()
      this.task = setInterval(() => {
        this.flapCardRotate()
      }, this.intervalTime)
    },
    // 旋转方法
    rotate (index, type) {
      const item = this.flapCardList[index]
      let dom
      if (type === 'front') {
        // 如果是前面，则获取左半圆取到第index个元素
        dom = this.$refs.right[index]
      } else {
        // 如果是后面，则获取右半圆元素
        dom = this.$refs.left[index]
      }
      dom.style.transform = `rotateY(${item.rotateDegree}deg)`
      dom.style.backgroundColor = `rgb(${item.r}, ${item._g}, ${item.b})`
    },
    prepare () {
      // 配置阶段
      // 1 、先把后面的背面素材，翻转180°，和上一个贴图的正面重合
      const backFlapCard = this.flapCardList[this.back]
      backFlapCard.rotateDegree = 180
      // 由于后面旋转图颜色会每次增加5度，增加9次重叠，所以要先减少相应的度数
      backFlapCard._g = backFlapCard._g - 5 * 9
      // 调用转动
      this.rotate(this.back, 'back')
    },
    // 1.2 卡片开始翻转
    flapCardRotate () {
      // 2、获取上一张图片和下一张图片
      const frontFlapCard = this.flapCardList[this.front]
      const backFlapCard = this.flapCardList[this.back]
      // 3、调整角度和颜色
      frontFlapCard.rotateDegree += 10
      frontFlapCard._g -= 5
      backFlapCard.rotateDegree -= 10
      // 当后面的图片显示状态才开始减少颜色
      if (backFlapCard.rotateDegree < 90) {
        backFlapCard._g += 5
      }
      // 4、当两个界面角度变成90°，上一张从0°增加10°到90°，下一张从180°每次减少10°到90°
      // 下一张的z-index增加，覆盖上一张
      if (frontFlapCard.rotateDegree === 90 && backFlapCard.rotateDegree === 90) {
        backFlapCard.zIndex += 2
      }
      // 5、开始旋转
      this.rotate(this.front, 'front')
      this.rotate(this.back, 'back')
      // 6、当转动到180°卡片重叠时候
      if (frontFlapCard.rotateDegree === 180 && backFlapCard.rotateDegree === 0) {
        this.next()
      }
    },
    next () {
      // 7、做完一组动画后，还原参数
      const frontFlapCard = this.flapCardList[this.front]
      const backFlapCard = this.flapCardList[this.back]
      frontFlapCard.rotateDegree = 0
      backFlapCard.rotateDegree = 0
      frontFlapCard._g = frontFlapCard.g
      backFlapCard._g = backFlapCard.g
      this.rotate(this.front, 'front')
      this.rotate(this.back, 'back')
      this.front++
      this.back++
      // 判断是否溢出
      const len = this.flapCardList.length
      if (this.front >= len) {
        this.front = 0
      }
      if (this.back >= len) {
        this.back = 0
      }
      // 动态设置zIndex
      // 100 -> 96
      // 99 -> 100
      // 98 -> 99
      // 97 -> 98
      // 96 -> 97
      // (0 - 1 + 5) % 5 = 4
      this.flapCardList.forEach((item, index) => {
        item.zIndex = 100 - ((index - this.front + len) % len)
      })
      this.prepare()
    },
    // 1.3 还原卡片状态
    reset () {
      this.front = 0
      this.back = 1
      this.flapCardList.forEach((item, index) => {
        item.zIndex = 100 - index
        item._g = item.g
        item.rotateDegree = 0
        this.rotate(index, 'front')
        this.rotate(index, 'back')
      })
      this.runBookCardAnimation = false
      this.runFlapCardAnimation = false
      this.runPointAnimation = false
    },
    // ****************** //
    // 小球动画
    startPointAnimation () {
      this.runPointAnimation = true
      setTimeout(() => {
        this.runPointAnimation = false
      }, 750)
    },
    // 返回目录名称
    categoryText () {
      if (this.data) {
        // 根据目录编号返回目录名字，采用国际化
        return categoryText(this.data.category, this)
      } else {
        return ''
      }
    }
  },
  // 实例创建前，先创建原点的数组，长度决定dom个数
  created () {
    this.pointList = []
    for (let i = 0; i < 18; i++) {
      this.pointList.push(`point${i}`)
    }
  }
}
</script>

<style lang="stylus" scoped>
  @import '../../assets/styles/global.styl'
  @import "../../assets/styles/flapCard.styl"
  @keyframes flap-card-move
    0%
      transform: scale(0)
      opacity: 0
    50%
      // 放大
      transform: scale(1.2)
      opacity: 1
    75%
      // 缩小
      transform: scale(.9)
      opacity: 1
    100%
      transform: scale(1)
      opacity: 1
  .flap-card-wrapper
    z-index: 1000
    width: 100%
    height: 100%
    // 蒙版
    background: rgba(0, 0, 0, .6)
    center()
    absCenter()
    .flap-card-bg
      position: relative
      width: px2rem(64)
      height: px2rem(64)
      border-radius: px2rem(5)
      background: white
      transform: scale(0)
      opacity: 0
      &.animation
        // ease-in表示进入毕竟迅速，后面速度变缓到正常，infinite表示无限循环,both将动画保持在100%
        animation: flap-card-move .3s ease-in both
      .flap-card
        // 循环出四个
        width: px2rem(48)
        height: px2rem(48)
        // 用绝对定位是为了DOM重叠到一起
        absCenter()
        .flap-card-circle
          display: flex
          width: 100%
          height: 100%
        .flap-card-semi-circle
          // 两个半圆，各占一半屏幕
          flex: 0 0 50%
          width: 50%
          height: 100%
          background-repeat: no-repeat
          // 转动到背面是显示状态设置为隐藏
          backface-visibility: hidden
        .flap-card-semi-circle-left
          border-radius: px2rem(24) 0 0 px2rem(24)
          // 左半部图片居中且居右
          background-position: center right
          transform-origin: right
        .flap-card-semi-circle-right
          border-radius: 0 px2rem(24) px2rem(24) 0
          background-position: center left
          transform-origin: left
    .point-wrapper
      // 定位处于中间位置
      z-index: 1500
      absCenter()
      .point
        border-radius: 50%
        // 圆点重叠起来
        absCenter()
        &.animation
          // 使用{}表示插值，直接将值输入进入，是stylus语法
          for $i in range(1, length($moves))
            &:nth-child({$i})
              moveAnimation($i - 1)
    .book-card
      position: absolute
      width: 65%
      max-width: px2rem(400)
      box-sizing: border-box
      border-radius: px2rem(15)
      background: white
      &.animation
        // 图书卡片缩放从无到有
        animation: scale .3s ease-in both
        @keyframes scale
          0%
            transition: scale(0)
            opacity: 0
          100%
            transition: scale(1)
            opacity: 1
      .book-card-wrapper
        width: 100%
        height: 100%
        margin-bottom: px2rem(30)
        columnTop()
        .img-wrapper
          width: 100%
          margin-top: px2rem(20)
          center()
          .img
            width: px2rem(90)
            height: px2rem(130)
        .content-wrapper
          padding: 0 px2rem(20)
          margin-top: px2rem(20)
          .content-title
            color: #333
            font-weight: bold
            font-size: px2rem(18)
            line-height: px2rem(20)
            max-height: px2rem(40)
            text-align: center
            ellipsis2(2)
          .content-author
            margin-top: px2rem(10)
            text-align: center
          .content-category
            color: #999
            font-size: px2rem(14)
            margin-top: px2rem(10)
            text-align: center
        .read-btn
          position: absolute
          bottom: 0
          left: 0
          z-index: 1100
          width: 100%
          border-radius: 0 0 px2rem(15) px2rem(15)
          padding: px2rem(15)
          box-sizing: border-box
          text-align: center
          color: white
          font-size: px2rem(14)
          background: $color-blue
    .close-btn-wrapper
      position: absolute
      bottom: px2rem(30)
      left: 0
      z-index: 1100
      width: 100%
      center()
      .iconfont
        width: px2rem(45)
        height: px2rem(45)
        border-radius: 50%
        background: #333
        font-size: px2rem(25)
        color: white
        center()
</style>
